package com.shelpe.services.auth.configuration;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import com.shelpe.services.auth.provider.request.OAuth2ReqeustFactory;
import com.shelpe.services.auth.provider.token.AdditionalJwtAccessTokenConverter;

@Configuration
public class JsonWebTokenConfiguration extends AuthorizationServerConfigurerAdapter{

	@Autowired
	private AuthenticationManager authenticationManager;
	@Autowired
	private StandardPasswordEncoder passwordEncoder;
	@Autowired
	private ClientDetailsService clientDetailsService;
	@Autowired
	@Qualifier("dataSource")
	private DataSource dataSource;

	@Bean
	public StandardPasswordEncoder passwordEncoder(){
		return new StandardPasswordEncoder("shelpe");
	}
	
	@Bean
	public JdbcClientDetailsService jdbcClientDetailsService(StandardPasswordEncoder passwordEncoder){
		JdbcClientDetailsService service = new JdbcClientDetailsService(this.dataSource);
		service.setPasswordEncoder(passwordEncoder);
		return service;
	}
	
	@Bean
	public JwtAccessTokenConverter jwtAccessTokenConverter() {
		JwtAccessTokenConverter converter = new AdditionalJwtAccessTokenConverter();
		return converter;
	}
	
	@Bean
	public DefaultAuthenticationKeyGenerator authenticationKeyGenerator(){
		DefaultAuthenticationKeyGenerator generator = new DefaultAuthenticationKeyGenerator();
		return generator;
	}
	
	@Bean
	public OAuth2ReqeustFactory oAuth2ReqeustFactory(){
		OAuth2ReqeustFactory factory = new OAuth2ReqeustFactory(this.clientDetailsService);
		return factory;
	}

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		clients.jdbc(this.dataSource).passwordEncoder(this.passwordEncoder).build();
	}

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints)
			throws Exception {
		endpoints.authenticationManager(authenticationManager);
		endpoints.accessTokenConverter(jwtAccessTokenConverter());
		endpoints.requestFactory(oAuth2ReqeustFactory());
	}

	@Override
	public void configure(AuthorizationServerSecurityConfigurer oauthServer)
			throws Exception {
		oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
	}
}
